class Scanner {
    declare private _inputStream: IStream
    constructor(iStream: IStream) {
        this._inputStream = iStream
    }
    scan(): Token {
        throw ''
    }

}
class Parser {
    parse(scanner: Scanner, programNodeBuilder: ProgramNodeBuilder) {

    }
}



class ProgramNodeBuilder {

    declare private _node: ProgramNode
    constructor() {
        this._node = new ProgramNode()
    }
    newVariable(variableName: string): ProgramNode {
        return this._node
    }
    newAssignment(variable: ProgramNode, expression: ProgramNode): ProgramNode {
        return this._node
    }
    newReturnStatement(value: ProgramNode): ProgramNode {
        return this._node
    }
    newCondition(condition: ProgramNode, truePart: ProgramNode, falsePart: ProgramNode): ProgramNode {
        return this._node
    }
    getRootNode(): ProgramNode {
        return this._node
    }

}
class ProgramNode {
    getSourcePosition(line: number, index: number) {

    }
    add(programNode: ProgramNode) { }
    remove(programNode: ProgramNode) { }
    traverse(codeGenerator: CodeGenerator) { }
}
class CodeGenerator {
    declare private _output: BytecodeStream
    constructor(bytecodeStream: BytecodeStream) {
        this._output = bytecodeStream
    }
    visit(node: StatementNode | ExpressionNode) {
        if (node instanceof StatementNode) {

        } else {
            //为ExpressionNode时
        }
    }

}
class BytecodeStream {

}
class StatementNode extends ProgramNode {
    traverse(codeGenerator: CodeGenerator): void {
        throw new Error("Method not implemented.")
    }

}
class ExpressionNode extends ProgramNode {
    declare programNodes: Array<ProgramNode>
    traverse(codeGenerator: CodeGenerator): void {
        codeGenerator.visit(this)
        for (let i = 0; i < this.programNodes.length; i++) {
            this.programNodes[i].traverse(codeGenerator)
        }
    }

}
class IStream {

}
class Token {
    declare token: string
    constructor(token: string) {
        this.token = token
    }
}
class RISCCodeGenerator extends CodeGenerator {

}
class Compiler {

    compile(input: IStream, output: BytecodeStream) {
        const scanner = new Scanner(input)
        const builder = new ProgramNodeBuilder()
        const parser = new Parser()
        parser.parse(scanner, builder)

        const generator = new CodeGenerator(output)
        const parseTree = builder.getRootNode()
        parseTree.traverse(generator)
    }

}


const compiler = new Compiler()
compiler.compile(new IStream(), new BytecodeStream())

